﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RentAWorker.DataAccess.Interfaces;
using RentAWorker.DataAccess.Entities;

namespace RentAWorker.Business.Impl.Util
{
    public class DataAccessDummy : ICustomerAccess, IResourceAccess, IRentalServiceAccess, IMachineTypeAccess, ILocationAccess
    {
        private static List<int> DeletedCustomers;
        private static List<int> DeletedResources;
        private static List<int> DeletedRentals;

        public DataAccessDummy()
        {
            if (DeletedCustomers == null) DeletedCustomers = new List<int>();
            if (DeletedResources == null) DeletedResources = new List<int>();
            if (DeletedRentals == null) DeletedRentals = new List<int>();
        }

        #region ICustomerAccess Members

        public Customer GetCustomerById(int customerId)
        {
            if (DeletedCustomers.Contains(customerId))
                return null;

            Customer c = new Customer();
            c.CustomerID = customerId;
            c.Name = string.Format("Customer {0}", customerId);
            c.MembershipID = Guid.Empty;
            c.RentalServices = null;
            return c;
        }

        public Customer GetCustomerByMembershipId(Guid membershipId)
        {
            int CId;
            Random Rnd = new Random();
            do
            {
                CId = Rnd.Next(1, 100);
            } while (DeletedCustomers.Contains(CId));

            Customer c = new Customer();
            c.CustomerID = CId;
            c.Name = string.Format("Customer 1");
            c.MembershipID = membershipId;
            c.RentalServices = null;
            return c;
        }

        public IEnumerable<Customer> GetCustomers(string searchString)
        {
            List<Customer> Response = new List<Customer>();

            Random Rnd = new Random();
            for (int i = 0; i < Rnd.Next(5, 10); i++)
            {
                Customer c = GetCustomerById(i + 1);
                if (!DeletedCustomers.Contains(c.CustomerID))
                    Response.Add(GetCustomerById(i + 1));
            }

            return Response;
        }

        public Customer CreateCustomer(Customer newCustomer)
        {
            if (DeletedCustomers.Contains(newCustomer.CustomerID))
                DeletedCustomers.Remove(newCustomer.CustomerID);
            return newCustomer;
        }

        public void DeleteCustomer(int customerId)
        {
            DeletedCustomers.Add(customerId);
        }

        public Customer UpdateCustomer(Customer customer)
        {
            return customer;
        }


        #endregion

        #region IResourceAccess Members

        public RentResource GetResource(int resourceID)
        {
            Location l = GetLocations(string.Empty).Single(ll => ll.LocationID == (resourceID % 10));
            MachineType m = GetMachineType(string.Empty).Single(mm => mm.MachineTypeID == (resourceID % 10));

            RentResource r;
            if (resourceID % 2 == 0)
            {
                r = new Worker()
                {
                    ResourceID = resourceID,
                    Name = "Worker " + resourceID,
                    SSNo = resourceID.ToString(),
                    Location = l
                };
            }
            else
            {
                r = new Machine()
                {
                    ResourceID = resourceID,
                    Name = "Machine " + resourceID,
                    SerialNo = resourceID.ToString(),
                    Status = "Status " + resourceID,
                    Location = l,
                    MachineType = m
                };
            }
            return r;
        }

        public IEnumerable<RentResource> GetResources()
        {
            return GetResources(string.Empty);
        }

        public IEnumerable<RentResource> GetResources(string nameSearchPattern)
        {
            List<RentResource> Response = new List<RentResource>();
            for (int i = 0; i < 100; i++)
            {
                RentResource Resource = GetResource(i + 1);
                if (!DeletedResources.Contains(Resource.ResourceID))
                    Response.Add(GetResource(i + 1));
            }
            return Response;
        }

        public IEnumerable<RentResource> GetAvailableResources(string nameSearchPattern, DateTime fromDate, DateTime toDate, int locationId, int? machineTypeId)
        {
            double Count = toDate.Subtract(fromDate).TotalDays;
            List<RentResource> Resources = (List<RentResource>)GetResources(string.Empty);
            List<RentResource> Response = new List<RentResource>();
            for (int i = 0; i < Resources.Count; i++)
            {
                if (!Resources[i].Name.StartsWith(nameSearchPattern))
                    continue;
                if (!(Resources[i].Location.LocationID == locationId))
                    continue;

                if(Response.Count <= Count)
                    Response.Add(Resources[i]);
            }

            // Return the response
            return Response;
        }

        public RentResource UpdateResource(RentResource updateResource)
        {
            return updateResource;
        }

        public RentResource CreateResource(RentResource newResource)
        {
            if (DeletedResources.Contains(newResource.ResourceID))
                DeletedResources.Remove(newResource.ResourceID);
            return GetResource(newResource.ResourceID);
        }

        public void DeleteResource(int resourceID)
        {
            DeletedResources.Add(resourceID);
        }

        #endregion

        #region IMachineTypeAccess Members

        public IEnumerable<MachineType> GetMachineType(string name)
        {
            List<MachineType> Response = new List<MachineType>();
            for (int i = 0; i < 10; i++)
            {
                Response.Add(new MachineType()
                {
                    MachineTypeID = (short)i,
                    MachineTypeName = "Machine Type " + i.ToString()
                });
            }
            return Response;
        }

        #endregion

        #region ILocationAccess Members

        public IEnumerable<Location> GetLocations(string searchName)
        {
            List<Location> Response = new List<Location>();
            for (int i = 0; i < 10; i++)
            {
                Location l = new Location()
                {
                    LocationID = (short)i,
                    LocationName = "Location " + i.ToString()
                };
                Response.Add(l);
            }
            return Response;
        }

        #endregion

        #region IRentalServiceAccess Members

        public RentalService GetRentalService(int rentalServiceId)
        {
            Random rnd = new Random();
            return GetRentalServiceHelper(rentalServiceId, rnd.Next(5, 10), rnd.Next(1, 20), null, null);
        }

        private RentalService GetRentalServiceHelper(int rentalServiceId, int customerId, int resourceId, DateTime? fromDate, DateTime? toDate)
        {
            Random Rnd = new Random();

            Customer Customer = GetCustomerById(customerId);
            if (Customer == null)
                throw new InvalidOperationException(string.Format("Customer with ID {0} does not exist!", customerId));
            RentResource Resource = GetResource(rentalServiceId);
            if (Resource == null)
                throw new InvalidOperationException(string.Format("Resource with id {0} does not exist!", resourceId));
            RentalServiceState State = GetRentalServiceStates().ElementAt(Rnd.Next(0, 2));

            DateTime Start = DateTime.Now.AddDays(Rnd.Next(5, 20));
            if (fromDate != null) Start = fromDate.Value;
            DateTime End = DateTime.Now.AddDays(Rnd.Next(20, 40));
            if (toDate != null) End = toDate.Value;

            return new RentalService()
            {
                RentalServiceID = rentalServiceId,
                Resource = Resource,
                RentalServiceState = State,
                StartDate = Start,
                EndDate = End,
                Customer = Customer
            };
        }

        public IEnumerable<RentalService> GetRentalServicesByCustomer(int customerId)
        {
            Random Rnd = new Random();
            List<RentalService> Response = new List<RentalService>();
            if (DeletedCustomers.Contains(customerId))
                return Response;
            for (int i = 0; i < customerId + 1; i++)
            {
                if (!DeletedRentals.Contains(i + 1))
                {
                    int resourceId = Rnd.Next(1, 20);
                    if (!DeletedResources.Contains(resourceId))
                        Response.Add(GetRentalServiceHelper(i + 1, customerId, resourceId, null, null));
                }
            }
            return Response;
        }

        public IEnumerable<RentalService> GetRentalServicesByState(string state, DateTime fromDate, DateTime toDate)
        {
            Random Rnd = new Random();
            List<RentalService> Response = new List<RentalService>();
            int Count = (int)toDate.Subtract(fromDate).TotalDays;
            for (int i = 0; i < Count; i++)
            {
                int resourceId = Rnd.Next(1, 20);
                if (!DeletedCustomers.Contains(i + 1) && !DeletedRentals.Contains(i + 1) && !DeletedResources.Contains(resourceId))
                    Response.Add(GetRentalServiceHelper(i + 1, i + 1, resourceId, fromDate, toDate));
            }
            return Response;
        }

        public IEnumerable<RentalService> GetRentalServicesByResource(int resourceId, DateTime fromDate, DateTime toDate)
        {
            Random Rnd = new Random();
            List<RentalService> Response = new List<RentalService>();
            if (DeletedResources.Contains(resourceId))
                return Response;
            int Count = (int)toDate.Subtract(fromDate).TotalDays;
            for (int i = 0; i < Count; i++)
            {
                if (!DeletedCustomers.Contains(i + 1) && !DeletedRentals.Contains(i + 1))
                    Response.Add(GetRentalServiceHelper(i + 1, i + 1, resourceId, fromDate, toDate));
            }
            return Response;
        }

        public RentalService UpdateRentalService(RentalService updateService)
        {
            return updateService;
        }

        public RentalService CreateRentalService(RentalService newService)
        {
            if (DeletedRentals.Contains(newService.RentalServiceID))
                DeletedRentals.Remove(newService.RentalServiceID);
            return newService;
        }

        public void DeleteRentalService(int rentalServiceId)
        {
            // No Implementation
        }

        public IEnumerable<RentalServiceState> GetRentalServiceStates()
        {
            List<RentalServiceState> States = new List<RentalServiceState>();
            States.AddRange
            (
                new RentalServiceState[] {
                    new RentalServiceState() { RentalServiceStateID = 1, RentalServiceStateName = "Requested" },
                    new RentalServiceState() { RentalServiceStateID = 1, RentalServiceStateName = "Approved" },
                    new RentalServiceState() { RentalServiceStateID = 1, RentalServiceStateName = "Declined" }
                }
            );
            return States;
        }

        #endregion
    }
}
